package model

import (
	"encoding/json"
	"fmt"
	"github.com/garyburd/redigo/redis"
	message "learningProject/shangguigu/common"
)

// 我们希望在服务器启动时就创建一个UserDAo实例，把他做成全局的，直接使用即可
var (
	MyUserDao *UserDao
)

// 定义一个UserDao结构体，完成对User结构体的各种操作
type UserDao struct {
	pool *redis.Pool
}

// 使用工厂模式创建UserDao实例
func NewUserDao(pool *redis.Pool) (userDao *UserDao) {
	userDao = &UserDao{
		pool: pool,
	}
	return
}

//1、根据用户id，返回user实例+error
func (this *UserDao) getUserByID(conn redis.Conn, id int) (user User, err error) {
	// 通过给定的id去redis里查询
	res, err := redis.String(conn.Do("HGet", "users", id))
	if err != nil {
		if err == redis.ErrNil {
			// id不存在
			err = ERROR_USER_NOTEXISTS
		}
		return
	}

	// 将res反序列为一个user实例
	json.Unmarshal([]byte(res), &user)
	if err != nil {
		fmt.Println("json.Unmarshal err", err)
	}

	return

}

// 完成登录的校验
// Login完成对用户的校验
// 如果用户id和密码都正确，则返回一个user实例
// 如果用户id或者密码错误，则返回对应的错误信息
func (this *UserDao) Login(userId int, userPwd string) (user User, err error) {
	// 先从 UserDao的连接池里取出一个连接
	conn := this.pool.Get()
	defer conn.Close()
	user, err = this.getUserByID(conn, userId)
	if err != nil {
		return
	}

	// 这里表示用户是存在的，接着验证用户密码是否正确
	if user.UserPwd != userPwd { // user.UserPwd是redis里得到的，userPwd是用户传进来的
		err = ERROR_USER_PWD
		return
	}

	return
}

// 注册
func (this *UserDao) Register(user *message.User) (err error) {
	// 先从 UserDao的连接池里取出一个连接
	conn := this.pool.Get()
	defer conn.Close()
	_, err = this.getUserByID(conn, user.UserId)
	if err == nil {
		err = ERROR_USER_EXISTS
		return
	}

	// 这里表示用户不存在的，可以注册
	data, err := json.Marshal(user) // 序列化
	if err != nil {
		return
	}
	// 入数据库
	_, err = conn.Do("Hset", "users", user.UserId, string(data))
	if err != nil { // user.UserPwd是redis里得到的，userPwd是用户传进来的
		fmt.Println("保存注册信息错误")
		return
	}

	return
}
